package top.zhangjianyong.tools.etf;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import top.zhangjianyong.tools.entity.ETF;
import top.zhangjianyong.tools.entity.ETFData;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.List;

/**
 * @author ： zhangjianyong
 * @date ： 2022/12/22 4:56 PM
 */
@Data
@Slf4j
public class ETFDayProcess {
    private ETF etf;
    private LocalDate date;
    private ETFManager etfManager;
    private ETFHolder etfHolder;

    private int day;//统计窗口大小

    private int hc;//回撤大于多少开始购买

    private int sy;//收益

    public ETFDayProcess(ETF etf, LocalDate date, ETFManager etfManager, int day, int hc, int sy) {
        this.etf = etf;
        this.date = date;
        this.etfManager = etfManager;
        this.etfHolder = etfManager.getEtfHold();
        this.day = day;
        this.hc = hc;
        this.sy = sy;
    }

    public boolean process() {
        String code = etf.getCode();
        if (!etfHolder.existByCodeAndDate(code, date)) {
            return true;
        }


        LocalDate start = date.plusDays(-day);
        LocalDate end = date;
        List<ETFData> etfDataList = etfHolder.listBetweenDate(code, start, end);
        ETFData current = etfDataList.get(etfDataList.size() - 1);
        //修改最新值
        etfHolder.setValue(etf, current.getTotalValue());
        //计算总收益
        BigDecimal rate = etfHolder.getETF(code).rate(current.getTotalValue());
        int realSy = sy;
        if (etfManager.isLowMoney()) {
            //剩余钱不多
            realSy = 2;
        }
        if (rate.compareTo(new BigDecimal(realSy)) > 0) {
            if (buyNum(etfDataList) < 0) {
                log.info("出售：{},{},{}", code, date, rate);
                etfManager.sell(date, etf, current.getTotalValue());
                return true;
            }

        }

        //计算需要买入几手
        int num = buyNum(etfDataList) * 100;
        if (num <= 0) return true;
        BigDecimal value = current.getTotalValue();
        BigDecimal money = value.multiply(new BigDecimal(num));
        log.info("计算：{},{}", code, date);
        log.info("买入：{}", num);
        log.info("金额：{}", money);
        return etfManager.buy(date, money, etf, num);
    }

    public int buyNum(List<ETFData> list) {
        BigDecimal base = new BigDecimal(100);
        setAveValue(list, base);
        ETFData current = list.get(list.size() - 1);
        //最大值
        BigDecimal max = list.stream().map(ETFData::getAvgValue).max(BigDecimal::compareTo).get();
        //最小值
        BigDecimal min = list.stream().map(ETFData::getAvgValue).min(BigDecimal::compareTo).get();
        //上升幅
        BigDecimal ssf = current.getAvgValue().subtract(min).divide(min, 4, RoundingMode.HALF_UP);

        //中位值
        BigDecimal rang = max.subtract(min);


        //回撤幅
        BigDecimal hcf = current.getAvgValue().subtract(max).divide(max, 4, RoundingMode.HALF_UP);
        int hc = hcf.negate().multiply(new BigDecimal(100)).intValue();

        if (rang.compareTo(BigDecimal.ZERO) > 0) {
            BigDecimal position = current.getAvgValue().subtract(min).divide(rang, 4, RoundingMode.HALF_UP);
            double v = position.doubleValue();
        }

       /* if (v > 0.20 && v < 0.3) {
            System.out.println("上升幅：" + current.getValueDate() + "  " + ssf.multiply(new BigDecimal(100)));
            return 1;
        }*/

        if (hc >= this.hc) {
            return 1;
        } else if (hc > 3) {
            return -1;
        }
        return 0;
    }

    /**
     * 初始化 辅助计算值
     *
     * @param list
     * @param base
     */
    public void setAveValue(List<ETFData> list, BigDecimal base) {
        BigDecimal cValueDate = null;
        for (ETFData e : list) {
            if (cValueDate == null) {
                cValueDate = base;
                e.setAvgValue(cValueDate);
            } else {
                cValueDate = cValueDate.multiply(e.getTotalRate());
                e.setAvgValue(cValueDate);
            }
        }
    }
}
